﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HSDc.RingleFlow.Api.Kernel;

namespace HSDc.RingleFlow.Kernel
{
    class ActivityInstance: Activity, ITask
    {
        private Activity _ActivityDefinition;
        private ProcessInstance _Instance;
        private TaskState _State;
        private string _Assignee;
        private Dictionary<string, object> _Variables = new Dictionary<string, object>();
        /// <summary>
        /// For Load Activity Instance
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="_ActivityDefinition"></param>
        /// <param name="_Assignee"></param>
        /// <param name="_instance"></param>
        /// <param name="state"></param>
        internal ActivityInstance(string _id, Activity _ActivityDefinition, string _Assignee, TaskState state)
            : base(_id)
        {
            this._ActivityDefinition = _ActivityDefinition;
            this._Assignee = _Assignee;
            this._State = state;
        }
        /// <summary>
        /// For New Activity Instance
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="_ActivityDefinition"></param>
        /// <param name="_Assignee"></param>
        /// <param name="_instance"></param>
        internal ActivityInstance(string _id, Activity _ActivityDefinition, string _Assignee,
            ProcessInstance _instance) : base(_id) 
        {
            this._ActivityDefinition = _ActivityDefinition;
            if ((!_ActivityDefinition.CanExecute) && (string.IsNullOrEmpty(_Assignee)))
                _Assignee = _ActivityDefinition.BelongSwimlane.DecideAssignee(((IProcessInstance)_instance).GetVaraibles());
            this._Assignee = _Assignee;
            this._Instance = _instance;
            this._State = TaskState.Open;
        }
        #region Interface Implementation
        string ITask.Id
        {
            get { return this._id; }
        }

        TaskState ITask.CurrentState
        {
            get { return _State; }
        }

        string ITask.Assignee
        {
            get { return _Assignee; }
        }

        void ITask.ChangeAssignee(string UserID)
        {
            this._Assignee = UserID;
        }

        string ITask.Description
        {
            get { return string.Empty; }
        }

        DateTime ITask.DueDate
        {
            get { return DateTime.Today.AddMonths(1); }
        }

        DateTime ITask.CreateTime
        {
            get { return DateTime.Now; }
        }

        void ITask.AddVariable(string VariableName, object variable)
        {
            _Variables.Add(VariableName, variable);
        }

        string ITask.TaskName
        {
            get { return _ActivityDefinition.Name; }
        }

        IProcessInstance ITask.Instance
        {
            get { return _Instance; }
        }
        #endregion

        internal string ActivityName
        {
            get { return _ActivityDefinition.Name; }
        }

        internal void Complete()
        {
            _State = TaskState.Completed;
            _Instance.FinishActivity(_ActivityDefinition.Id, _id, this._Variables);
        }

        internal bool ContainsAssignee(string Assignee)
        {
            return _Assignee.Equals(Assignee);
        }

        internal string ActivityDefinitionId
        {
            get { return _ActivityDefinition.Id; }
        }

        internal void SetProcessInstance(ProcessInstance pi)
        {
            this._Instance = pi;
        }

        internal Dictionary<string, object> Variables
        {
            get { return _Variables; }
            set { _Variables = value; }
        }

        internal Type ActivityDefinitionType
        {
            get { return _ActivityDefinition.GetType(); }
        }

        internal override bool CanExecute
        {
            get
            {
                return _ActivityDefinition.CanExecute;
            }
        }

        internal void SetState(TaskState state)
        {
            _State = state;
        }

        internal override List<Transition> InboundTransitions
        {
            get
            {
                return _ActivityDefinition.InboundTransitions;
            }
        }
    }
}
